using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using Dimebrain.TweetSharp.Core.Extensions;
using Dimebrain.TweetSharp.Extensions;
using Dimebrain.TweetSharp.Fluent;
using Dimebrain.TweetSharp.Model;

namespace visualtwimilar
{
  public static class Extensions
  {
    private static readonly Cache.Cache _cache;

    static Extensions()
    {
      _cache = new Cache.Cache();
    }

    public static IEnumerable<string> GetFriends(this string person)
    {
      Func<string, IList<string>> getFriends = (param =>
                                                  {
                                                    decimal ceiling = Math.Ceiling(
                                                      FluentTwitter.CreateRequest()
                                                        .Users().ShowProfileFor(param).AsJson()
                                                        .Request().AsUser().FollowersCount / 100m
                                                      );
                                                    var results = new List<string>();
                                                    for (int i = 1; i <= ceiling; i++)
                                                    {
                                                      IEnumerable<TwitterUser> users = FluentTwitter.CreateRequest().
                                                        Users().GetFriends().For(param)
                                                        .Skip(i).AsJson().Request().AsUsers();

                                                      results.AddRange(users.Map(x => x.ScreenName));
                                                    }

                                                    return results;
                                                  });
      return _cache.Init(getFriends, person);
    }

    public static IEnumerable<string> GetUsersWhoTwitThis(this string word)
    {
      Func<string, IList<string>> getUsersWhoTwitThis = ((param) =>
                                                  {

                                                    XDocument feed = XDocument.Parse(
                                                      FluentTwitter.CreateRequest().Search()
                                                        .Query().Containing(param).Take(3).AsAtom().Request()
                                                      );

                                                    return feed.Root.Elements()
                                                      .Where(x => x.Name.LocalName == "entry")
                                                      .Elements()
                                                      .Where(x => x.Name.LocalName == "author")
                                                      .Elements()
                                                      .Where(x => x.Name.LocalName == "uri")
                                                      .ToList()
                                                      .Map(x => x.Value.ToPersonName()).ToList();
                                                  });
      return _cache.Init(getUsersWhoTwitThis, word);
    }

    public static string ToPersonName(this string url)
    {
      return Regex.Replace(url, "http://twitter.com/", string.Empty);
    }

    public static IDictionary<string, IDictionary<string, double>> LoadForUser(
      this IDictionary<string, IDictionary<string, double>> prefs, string person)
    {
      if (!prefs.Keys.Contains(person))
        prefs[person] = new Dictionary<string, double>();

      Func<string, IList<string>> getEntries = ((param) =>
                                                        {
                                                          XDocument feed = XDocument.Parse(
                                                            FluentTwitter.CreateRequest().Search().Query()
                                                              .FromUser(param).AsAtom().Request()
                                                            );
                                                          IEnumerable<string> feedentries = from x in feed.Root.Elements()
                                                                                            where x.Name.LocalName == "entry"
                                                                                            select x.Elements()
                                                                                              .Where(
                                                                                              element =>
                                                                                              element.Name.LocalName == "title")
                                                                                              .First()
                                                                                              .Value;
                                                          return feedentries.ToList();
                                                        });
      var entries = _cache.Init(getEntries, person);
      foreach (string entry in entries)
      {
        foreach (string word in Regex.Split(entry, @"\W"))
        {
          if (string.IsNullOrEmpty(word) || word.Length < 3)
            continue;

          if (!prefs[person].Keys.Contains(word))
            prefs[person][word] = 0;
          prefs[person][word] += 1;
        }
      }
      return prefs;
    }
  }
}